<script setup lang="ts">
import { computed } from 'vue';

import { getDictObj } from '@vben/hooks';
import { isValidColor, TinyColor } from '@vben/utils';

import { Tag } from 'ant-design-vue';

interface DictTagProps {
  /**
   * 字典类型
   */
  type?: string;
  /**
   * 字典值
   */
  value: any;
  /**
   * 字典选项
   */
  options?: any;
  /**
   * 图标
   */
  icon?: string;
  /**
   * 颜色类型
   */
  colorType?: string;
}

const props = defineProps<DictTagProps>();
const colorList = [
  'blue',
  'orange',
  'yellow',
  'green',
  'red',
  'cyan',
  'purple',
  'geekblue',
  'magenta',
  'volcano',
  'saffron',
  'gold',
  'lime',
  'teal',
  'cyan',
  'blue',
  'purple',
  'geekblue',
  'magenta',
  'volcano',
  'saffron',
  'gold',
  'lime',
  'teal',
];

/** 获取字典标签 */
const dictTag = computed(() => {
  // 校验参数有效性
  if (props.value === undefined || props.value === null) {
    return [];
  }
  let valueList = [];
  if (Array.isArray(props.value)) {
    if (props.value.length === 0) {
      return [];
    } else {
      valueList = props.value;
    }
  } else {
    valueList = [props.value];
  }
  const dictTagList = [];
  let colorIndex = 0;
  for (const item of valueList) {
    let dict = null;
    if (props.type) {
      // 获取字典对象
      dict = getDictObj(props.type, String(item));
      if (!dict) {
        continue;
      }
    } else {
      let myOptions = props.options;
      if (myOptions === null || myOptions === undefined) {
        myOptions = [
          { label: '是', value: true, colorType: 'primary' },
          { label: '否', value: false, colorType: 'danger' },
        ];
      }

      dict =
        myOptions.find(
          (d) => d.value === item || d.value === item.toString(),
        ) ?? null;
    }
    if (!dict) {
      dict = {
        label: item,
      };
    }

    // 处理颜色类型
    let colorType = props.colorType || dict.colorType;
    switch (colorType) {
      case 'danger': {
        colorType = 'error';
        break;
      }
      case 'info': {
        colorType = 'default';
        break;
      }
      case 'primary': {
        colorType = 'processing';
        break;
      }
      default: {
        if (!colorType) {
          colorType = 'default';
        }
      }
    }
    // 处理颜色类名
    if (!dict.colorType && !props.colorType) {
      if (isValidColor(dict.cssClass)) {
        colorType = new TinyColor(dict.cssClass).toHexString();
      } else {
        if (colorIndex < valueList.length) {
          colorType = colorList[colorIndex];
        } else {
          // 超过颜色列表长度，循环使用
          colorType = colorList[colorIndex % valueList.length];
        }
      }
    }
    colorIndex++;
    dictTagList.push({
      label: dict.label || '',
      colorType,
      cssClass: dict.cssClass,
    });
  }
  return dictTagList;
});
</script>

<template>
  <Tag
    v-for="(item, index) in dictTag"
    :key="index"
    :color="item.colorType ? item.colorType : item.cssClass"
  >
    {{ item.label }}
  </Tag>
</template>
